package com.xph.core.common.util;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/** JSON工具
 * 
 * @author Administrator */
public class JsonUtil
{

    public static List<Map<String, Object>> jsonArray2List(JSONArray jsonArray) throws Exception
    {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < jsonArray.length(); i++)
        {
            list.add(json2Map(jsonArray.getJSONObject(i)));
        }
        return list;
    }
    
    public static List<Map<String, Object>> jsonArrays2List(JSONArray jsonArray) throws Exception
    {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < jsonArray.length(); i++)
        {
            if(jsonArray.get(i).getClass()==JSONArray.class)
            {
                List<Map<String, Object>> list2 = new ArrayList<Map<String, Object>>();
                JSONArray jsonArray2 = (JSONArray)jsonArray.get(i);
                for (int j = 0; j < jsonArray2.length(); j++)
                {
                    list2.add(json2Map(jsonArray2.getJSONObject(j)));
                }
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("list" + i, list2);
                list.add(map);
            }
            else
            {
                list.add(json2Map(jsonArray.getJSONObject(i)));
            }
        }
        return list;
    }

    public static Map<String, Object> json2Map(JSONObject jsonObject) throws Exception
    {
        Iterator<String> keyIter = jsonObject.keys();
        String key;
        Object value;
        Map<String, Object> map = new HashMap<String, Object>();
        while (keyIter.hasNext())
        {
            key = (String) keyIter.next();
            value = jsonObject.get(key);
            map.put(key, value);
        }
        return map;
    }

    public static JSONObject map2Json(Map map)
    {
        return new JSONObject(map);
    }

    public static JSONArray list2JsonArray(List<Map<String, Object>> list)
    {
        JSONArray jsonArray = new JSONArray();
        for (int i = 0; i < list.size(); i++)
        {
            jsonArray.put(map2Json(list.get(i)));
        }
        return jsonArray;
    }

    public static JSONObject obj2Json(Object obj)
    {
        JSONObject json= new JSONObject(obj);
        //获得父类中对应的所有属性域
        Field[] fields = obj.getClass().getSuperclass().getDeclaredFields();
        for(Field field: fields){
            // 设置字段可访问（必须，否则报错）
            field.setAccessible(true);
            // 得到字段的属性名
            String name = field.getName();
            // 这一段的作用是如果字段在JSONObject中不存在会抛出异常，如果出异常，则跳过。
            try
            {
                Object o = field.get(obj);
                json.put(name, o);
            }
            catch (IllegalArgumentException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IllegalAccessException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (JSONException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return json;
    }
    
    public static Object json2Bean (JSONObject json,Class clazz) throws Exception{
     // 根据传入的Class动态生成pojo对象
        Object obj = clazz.newInstance();
        // 首先得到pojo所定义的字段
        Field [] fields = clazz.getDeclaredFields();       
        setObjFields(obj,json,fields);
        //设置父类属性值
        Field[] parentFields = clazz.getSuperclass().getDeclaredFields();
        setObjFields(obj,json,parentFields);
        return obj;
    }
    
    private static void setObjFields(Object obj,JSONObject json,Field[] fields) throws NumberFormatException, IllegalArgumentException, JSONException, IllegalAccessException, ParseException{
        for(Field field1: fields){
            // 设置字段可访问（必须，否则报错）
            field1.setAccessible(true);
            // 得到字段的属性名
            String name = field1.getName();
            // 这一段的作用是如果字段在JSONObject中不存在会抛出异常，如果出异常，则跳过。
            try{
                  json.get(name);
            }catch(Exception ex){
                continue;
            }
            if(json.get(name) != null && !"".equals(json.getString(name)) && !"null".equals(json.getString(name))){
                // 根据字段的类型将值转化为相应的类型，并设置到生成的对象中。
                if(field1.getType().equals(Long.class) || field1.getType().equals(long.class)){
                    field1.set(obj, Long.parseLong(json.getString(name)));
                }else if(field1.getType().equals(String.class)){
                    field1.set(obj, json.getString(name));
                } else if(field1.getType().equals(Double.class) || field1.getType().equals(double.class)){
                    field1.set(obj, Double.parseDouble(json.getString(name)));
                } else if(field1.getType().equals(Integer.class) || field1.getType().equals(int.class)){
                    field1.set(obj, Integer.parseInt(json.getString(name)));
                } else if(field1.getType().equals(java.util.Date.class)){
                    SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);    
                    field1.set(obj, sdf.parse(json.getString(name)));
                } else if(field1.getType().equals(boolean.class)){
                    field1.set(obj, Boolean.parseBoolean(json.getString(name)));
                }else{
                    continue;
                }
            }
        }
    }
    
    public static boolean isNull(JSONObject obj,String fieldname) throws JSONException{
        if(!obj.has(fieldname))
            return true;
        if(obj.isNull(fieldname))
            return true;
        if(obj.getString(fieldname).equals(""))
            return true;
        else
            return false;
    }
}
